package com.genghis.ptas.scorm.service.impl;

import com.genghis.ptas.scorm.service.ValidateImageService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Random;

/**
 * Created with IntelliJ IDEA.
 * User: tiangc
 * Date: 14-4-22
 * Time: 下午8:16
 * To change this template use File | Settings | File Templates.
 */
@Transactional
@Service("validateImageService")
public class ValidateImageServiceImpl implements ValidateImageService {
    private static int WIDTH = 60;
    private static int HEIGHT = 20;
    private String oldCode="";
    @Override
    public void validateImage(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession();
        response.setContentType("image/jpeg");
        ServletOutputStream sos = response.getOutputStream();

        //设置浏览器不要缓存此图片
        response.setHeader("Pragma","No-cache");
        response.setHeader("Cache-Control","no-cache");
        response.setDateHeader("Expires", 0);

        //创建内存图象并获得其图形上下文
        BufferedImage image =
                new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
        Graphics g = image.getGraphics();

        //产生随机的认证码
        char [] rands = generateCheckCode();

        //产生图像
        drawBackground(g);
        drawRands(g,rands);

        //结束图像的绘制过程，完成图像
        g.dispose();

        //将图像输出到客户端
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ImageIO.write(image, "JPEG", bos);
        byte [] buf = bos.toByteArray();
        response.setContentLength(buf.length);
        //下面的语句也可写成：bos.writeTo(sos);
        sos.write(buf);
        bos.close();
        sos.close();

        //将当前验证码存入到Session中
        session.setAttribute("check_code",new String(rands));
        //直接使用下面的代码将有问题，Session对象必须在提交响应前获得,因为这里已经把输出流都关闭了,而这里还要request.getSession()操作,这个操作需要给浏览器送一个sessionID过去
        //request.getSession().setAttribute("check_code",new String(rands));
    }



    private char [] generateCheckCode()
    {
        //定义验证码的字符表
        String chars = "0123456789abcdefghijklmnopqrstuvwxyz";
        char [] rands = new char[4];
        for(int i=0; i<4; i++)
        {
            int rand = (int)(Math.random() * 36);
            rands[i] = chars.charAt(rand);
        }
        return rands;
    }

    private void drawRands(Graphics g , char [] rands)
    {
        g.setColor(Color.BLACK);
        g.setFont(new Font(null,Font.ITALIC|Font.BOLD,18));
        //在不同的高度上输出验证码的每个字符
        int[] highs = getImageHigh();
        int[] widths = getImageWidth();//在不同的x左边上输出验证码的每个字符
        g.drawString("" + rands[0],widths[0],highs[0]);
        g.drawString("" + rands[1],widths[1],highs[1]);
        g.drawString("" + rands[2],widths[2],highs[2]);
        g.drawString("" + rands[3],widths[3],highs[3]);
        oldCode=String.valueOf(rands);
    }
    @Override
    public Boolean checkImageCode(String imageCode) {
          return imageCode.equals(oldCode);
    }
    private void drawBackground(Graphics g)
    {
        //画背景
        g.setColor(new Color(0xDCDCDC));
        g.fillRect(0, 0, WIDTH, HEIGHT);
        //随机产生520个干扰点
        for(int i=0; i<520; i++)
        {
            int x = (int)(Math.random() * WIDTH);
            int y = (int)(Math.random() * HEIGHT);
            int red = (int)(Math.random() * 255);
            int green = (int)(Math.random() * 255);
            int blue = (int)(Math.random() * 255);
            g.setColor(new Color(red,green,blue));
            g.drawOval(x,y,1,0);
        }
    }

    //随即产生验证码中四个字的高度   这个方法等同于Random dom = new Random();  int rand = 10+dom.nextInt(9);
    private int[] getImageHigh(){
        String[] highs = {"12","13","14","15","16","17","18"};
        int[] rands = new int[4];
        for(int i=0; i<4; i++)
        {
            int rand = (int)(Math.random() * 7);
            rands[i] = Integer.parseInt(highs[rand]);
        }
        return rands;
    }

    //随即产生验证码中四个字的高度
    private int[] getImageWidth(){
        int[] rands = new int[4];
        Random dom = new Random();
        rands[0] = 1+dom.nextInt(4);//在一个范围中产生随机数  包括前面不包括后面  这里是1-3
        rands[1] = 15+dom.nextInt(3);//15-17
        rands[2] = 30+dom.nextInt(3);
        rands[3] = 45+dom.nextInt(3);
        return rands;
    }

}
